
#include <asm.h>

.global C_SYMBOL(Blit_8u_C4A)


C_SYMBOL(Blit_8u_C4A):

    STMFD	SP!, {R4-R8,LR}
    MOV	LR, R0

    LDR R0, [LR, #0x0]                 //pSrc
    LDR	R1, [LR, #0x8]                 //SrcStep
    LDR	R2, [LR, #0x4]                 //pDst
	LDR	R3, [LR, #0xC]                 //DstStep

    LDR	R4, [LR, #0x10]                 //width
    LDR	R5, [LR, #0x14]                 //height
    MOV R4, R4, LSL #2

//	LDR	R8, [LR, #0x18]                 //color


    SUB	R1, R1,	R4                          //R1 = SRC pitch - ROI width
    SUB	R3, R3,	R4                          //R3 = DST pitch - ROI width

//.long 0xe7fddefe
_Line_Start_:
    MOV	R6, R4                              //R6 = ROI width
    ADD	R7, R2,	#7                          //R2 = destination pointer
    BIC	R7, R7,	#7                          //Ceiling R7 ADDRESS to 8 byte aligned, suppose jumped N
    SUB	R7, R7,	R2                          //
    CMP	R7, #0                              //Compare to see if R7 is originally 8 byte aligned
    BEQ	_lc030_000669_                      //if so jump to _lc030_000669_

_Less_Than_32_:
    WLDRW   wR0 ,[R0], #4                   //R0 = Source pointer, LOAD 4 byte

    CMP	R7, R6                              //
    MOVGT	R7, R6                          //Let R7 be the min(N , width)
    SUB	R6, R6,	R7                          //Let R6 be width - N

_Process_Step_N_header_:                             //:SAVE N byte
    SUBS	R7, R7,	#4                      //N--, modify CPSR
    WSTRW   wR0 ,[R2], #4                   //SAVE 4 byte
    WLDRWGT   wR0 ,[R0], #4                 //if width > N, LOAD 1 byte again

    BGT	_Process_Step_N_header_                      //if width > N, jump to _Process_Step_N_header_
    CMP	R6, #0
    BEQ	_Next_Line_                         //if R6 = width - N == 0 jump to _Next_Line_

_lc030_000669_:
    SUBS	R6, R6,	#0x20                   //R6 -= 32 byte
    ADDMI	R7, R6,	#0x20
    ADDMI	R6, R6,	#0x20
    BMI	_Less_Than_32_                      //jumpt to _Less_Than_32_ if less than 32 byte
    TST	R0, #7
    BNE	_UnAligned8_                        //if pSrc is not 8 byte aligned jump to _UnAligned8_

    WLDRD   wR0, [R0], #8
    WLDRD   wR1, [R0], #8

_Loop_Aligned8_:
    PLD	[R0,#0x40]
    PLD	[R2,#0x40]

    WSTRD   wR0, [R2], #8
    WLDRD   wR2, [R0], #8
    WSTRD   wR1, [R2], #8
    WLDRD   wR3, [R0], #8

    SUBS	R6, R6,	#0x20

    WSTRD   wR2, [R2], #8
    WLDRDGE wR0, [R0], #8
    WSTRD   wR3, [R2], #8
    WLDRDGE wR1, [R0], #8

    BGE	_Loop_Aligned8_

    ADDS	R6, R6,	#0x20
    BEQ	_Next_Line_
    MOVGT	R7, R6
    BGT	_Less_Than_32_

_UnAligned8_:
    AND	R7, R0,	#7
    BIC	R0, R0,	#7
    TMCR    wCGR0, R7
    WLDRD   wR0, [R0], #8
    WLDRD   wR1, [R0], #8
    WLDRD   wR2, [R0], #8
    WLDRD   wR3, [R0], #8

_Loop_UnAligned8_:
    SUBS	R6, R6,	#0x20
    PLD	[R0,#0x40]
    PLD	[R2,#0x40]
    WLDRD   wR4, [R0]

    WALIGNR0 wR0 ,wR0, wR1
    WSTRD   wR0, [R2], #8
    WLDRDGE wR0, [R0], #8

    WALIGNR0 wR1 ,wR1, wR2
    WSTRD   wR1, [R2], #8
    WLDRDGE wR1, [R0], #8

    WALIGNR0 wR2 ,wR2, wR3
    WSTRD   wR2, [R2], #8
    WLDRDGE wR2, [R0], #8

    WALIGNR0 wR3, wR3, wR4
    WSTRD   wR3, [R2], #8
    WLDRDGE wR3, [R0], #8

    BGE	_Loop_UnAligned8_
    ADD	R0, R0,	R7
    ADDS	R6, R6,	#0x20
    BEQ	_Next_Line_
    MOVGT	R7, R6
    BGT	_Less_Than_32_

_Next_Line_:
    ADD	R0, R0,	R1
    ADD	R2, R2,	R3
    SUBS	R5, R5,	#1
    BGT	_Line_Start_
    LDMFD	SP!, {R4-R8,PC}
